*******************************************************************************
* Print Record Spy
*
* (C)  Copyright Apple Computer, Inc. 1988
* All rights reserved.
*
* by Keith Rollin
* based on a story by Scott 'ZZ' Zimmerman
* June 30, 1988
*
* This program lets the avid and interested user examine the various
* fields of the Print Record used by the Print Manager. Menu items let you
* call Print Manager routines, and this program will display the values from
* the resulting print record in a window. It also keeps track of past values
* of the print record, and notes the fields that have changed by displaying
* them in Boldface. A second window displays the past values so you can
* compare them with the changed values side by side.
*
* Files: System macros and equates.
*        Spy.inits.aii
*
*
* Modification History:
*
* Version 1.0       Keith Rollin
*
*      June 30, 1988
*
*      First Release
*
*******************************************************************************

**********************************************************************
*                                                                    *
*             Apple IIGS Source Code Sampler, Volume I               *
*                                                                    *
*             Copyright (c) Apple Computer, Inc. 1988                *
*                       All Rights Reserved                          *
*                                                                    *
*            Written by Apple II Developer Tech Support              *
*                                                                    *
*                                                                    *
*                                                                    *
*  ----------------------------------------------------------------  *
*                                                                    *
*     This program and its derivatives are licensed only for         *
*     use on Apple computers.                                        *
*                                                                    *
*     Works based on this program must contain and                   *
*     conspicuously display this notice.                             *
*                                                                    *
*     This software is provided for your evaluation and to           *
*     assist you in developing software for the Apple IIGS           *
*     computer.                                                      *
*                                                                    *
*     DISCLAIMER OF WARRANTY                                         *
*                                                                    *
*     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
*     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
*     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
*     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
*     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
*     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
*     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
*     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
*     REPAIR OR CORRECTION.                                          *
*                                                                    *
*     Apple does not warrant that the functions                      *
*     contained in the Software will meet your requirements          *
*     or that the operation of the Software will be                  *
*     uninterrupted or error free or that defects in the             *
*     Software will be corrected.                                    *
*                                                                    *
*     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
*     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
*     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
*     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
*     WHICH VARY FROM STATE TO STATE.                                *
*                                                                    *
*                                                                    *
**********************************************************************


                    mcopy spy.macros
                    copy 2/ainclude/E16.Quickdraw
                    copy 2/ainclude/E16.Memory
                    copy 2/ainclude/E16.Window
                    copy 2/ainclude/E16.Dialog
                    copy 2/ainclude/E16.Print

*******************************************************************************
*
*    Equates used in this program.
*
*******************************************************************************
DPHandle           gequ 0               ; Handle to Tool Direct Page area
DPPointer          gequ DPHandle+4      ; Pointer to Tool Direct Page area
deref              gequ DPPointer+4     ; Temprary Handle dereference area
Temp1              gequ deref+4
Temp2              gequ Temp1+4

ScreenMode         gequ Mode640
ScreenWidth        gequ 640


                    EJECT
*******************************************************************************
*
Main                start
*
* Description:      This is the main routine. It calls routines to Initialize
*                   the tools, initialize application specific data, run the
*                   main EventLoop, close the application, and close the tools.
*                   Then it calls the ProDOS Quit command.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import InitTools
*                   Import InitApp
*                   Import EventLoop
*                   Import CloseApp
*                   Import CloseTools
*                   Import QuitParms
*
* Entry Points:     NONE
*
*******************************************************************************
                    Using globals

                    jsr InitTools
                    jsr InitApp

                    _ShowCursor

                    jsr EventLoop
                    jsr CloseApp
                    jsr CloseTools

                    _Quit QuitParms

                    end

                    EJECT
*******************************************************************************
*
Globals             data
*
* Description:      Holder of all of our data.
*
*
* Inputs:           N/A
*
* Outputs:          N/A
*
* External Refs:
*                   Import PrUpdate
*                   Import PrOldUpdate
*
* Entry Points:
*                   Export QuitParms    ; used by Main
*
*******************************************************************************
*
* Standard global data
*
*******************************************************************************

TitleString       str 'Print Record Spy - Shows effects of Print Manager calls'
AutString           str 'By Keith Rollin Apple DTS (c)1988 Apple Computer'
VersString          str 'Version: 1.0'

MenuHeight          ds 2                ; Stored height of menu bar
MyID                ds 2                ; Application ID
MyDP                ds 2                ; My direct page storage

QuitFlag            ds 2
QuitParms           dc i4'0'            ; Pathname of next app
                    dc i2'$00'          ; flags

EventRecord         ANOP
EventWhat           ds 2
EventMessage        ds 4
EventWhen           ds 4
EventWhere          ds 4
EventModifiers      ds 2
TaskData            ds 4
TaskMask            dc i4'$0000FFFF'

                    EJECT
*******************************************************************************
*
* Application specific global data
*
*******************************************************************************

; This is a list of pointers to the text that is used to create our menus. It
; is used by InitApp to find all of the menu templates and use them to create
; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
; corresponding menu template pointer in this table, and uses that in a
; NewMenu call. It then decrements the index by 4, and repeats the procees
; until the index is negative.

MenuPtr             dc i4'AppMenu'
                    dc i4'FileMenu'
                    dc i4'EditMenu'
MenuPtrLen          equ *-MenuPtr


; Menu list: menu items should be numbered consecutivly starting from 250.
; As a convention, use 256 as about and 257 as Quit.

AppMenu             dc c'$$@\N1',h'0D'
                    dc c'--About Print Record Spy...\N256V',h'0D'
                    dc c'.'
FileMenu            dc c'$$  File  \N2',h'0D'
                    dc c'--Choose Printer\N258',h'00'
                    dc c'--Page Setup\N259',h'00'
                    dc c'--Job Dialog\N260',h'00'
                    dc c'--PrDefault\N261',h'00'
                    dc c'--PrValidate\N262V',h'00'
                    dc c'--Quit\N257*Qq',h'0D'
                    dc c'.'
EditMenu            dc c'$$  Edit  \N3',h'00'
                    dc c'--Undo\N250*ZzVD',h'00'
                    dc c'--Cut\N251*XxD',h'00'
                    dc c'--Copy\N252*CcD',h'00'
                    dc c'--Paste\N253*VvD',h'00'
                    dc c'--Clear\N254D',h'00'
                    dc c'.'

;
; Parameters lists for my two windows
;
wTitle1             str '  Current Settings  '
MyWindow            dc i2'WindEnd-MyWindow' ; size of paramBlock
                    dc i2'fVis+fTitle+fBScroll+fRScroll+fGrow+fMove+fZoom'
                    dc i4'wTitle1'      ; no title bar, no title...
                    dc i4'0'            ; RefCon
                    dc i2'30,60,185,580'                    ; zoomed rect
                    dc i4'0'            ; color table = default
                    dc i2'0,0'          ; scroll bar XY origin
                    dc i2'155,520'      ; scroll max.
                    dc i2'155,520'      ; Max Height/Width.
                    dc i2'40,40'        ; scroll values
                    dc i2'0,0'          ; page values (default)
                    dc i4'0'            ; no info bar RefCon
                    dc i2'0'            ; info bar height (none)
                    dc i4'0'            ; Frame defproc, NIL=standard
                    dc i4'0'            ; no info bar def proc
                    dc i4'PRUpdate'     ; auto updates
                    dc i2'30,10,185,290'                    ; bounds rect.
                    dc i4'$FFFFFFFF'    ; plane= on top.
                    dc i4'0'            ; NIL storage pointer
WindEnd             equ *

wTitle2             str '  Previous Settings  '
MyWindow2           dc i2'WindEnd2-MyWindow2' ; size of paramBlock
                    dc i2'fVis+fTitle+fBScroll+fRScroll+fGrow+fMove+fZoom'
                    dc i4'wTitle2'      ; no title bar, no title...
                    dc i4'0'            ; RefCon
                    dc i2'30,60,185,580'                    ; zoomed rect
                    dc i4'0'            ; color table = default
                    dc i2'0,0'          ; scroll bar XY origin
                    dc i2'155,520'      ; scroll max.
                    dc i2'155,520'      ; Max Height/Width.
                    dc i2'40,40'        ; scroll values
                    dc i2'0,0'          ; page values (default).
                    dc i4'0'            ; no info bar RefCon
                    dc i2'0'            ; info bar height (none)
                    dc i4'0'            ; Frame defproc, NIL=standard
                    dc i4'0'            ; no info bar def proc
                    dc i4'PROldUpdate'  ; auto updates
                    dc i2'30,330,185,610'                   ; bounds rect.
                    dc i4'$FFFFFFFF'    ; plane= on top.
                    dc i4'0'            ; NIL storage pointer
WindEnd2            equ *


WindPointer         ds 4
WindPointer2        ds 4

BigRect             dc i2'0,0,200,640'
PrintRecord         ds 4
OldRecord           ds 4
PrinterPort         ds 4


; Big hunkin' chunk of data that I use to print the strings. These are
; their X/Y coordinates.

Position            dc i2'10,10'        ; Print Record
                    dc i2'270,10'       ; Printer Information
                    dc i2'270,70'       ; Job SubRecord
                    dc i2'10,80'        ; Style SubRecord
                    dc i2'20,20'        ; prVersion
                    dc i2'20,30'        ; prInfo
                    dc i2'20,40'        ; rPaper
                    dc i2'20,50'        ; prStl
                    dc i2'20,60'        ; prJob
                    dc i2'280,20'       ; iDev
                    dc i2'280,30'       ; iVRes
                    dc i2'280,40'       ; iHRes
                    dc i2'280,50'       ; rPage
                    dc i2'20,90'        ; wDev
                    dc i2'20,100'       ; feed
                    dc i2'20,110'       ; paperType
                    dc i2'20,120'       ; crWidth/vSizing
                    dc i2'20,130'       ; reduction
                    dc i2'280,80'       ; iFstPage
                    dc i2'280,90'       ; iLstPage
                    dc i2'280,100'      ; iCopies
                    dc i2'280,110'      ; bJDocLoop
                    dc i2'280,120'      ; pIdleProc
                    dc i2'280,130'      ; pFileName
                    dc i2'280,140'      ; iFileVol
                    dc i2'280,150'      ; bFileVers


; Big hunkin' chunk of data that I use to print the record's values.
; The Low word is the offset into the print record that I'm interested
; in. The high word contains the length of the field that I'm printing. If
; it's Zero, then no values get printed at all. For instance, some
; strings don't get any values printed after them.

ValueOffsets        dc i4'$00000000'    ; Print Record
                    dc i4'$00000000'    ; Printer Information
                    dc i4'$00000000'    ; Job SubRecord
                    dc i4'$00000000'    ; Style SubRecord
                    dc i4'$00010000'    ; prVersion
                    dc i4'$00000000'    ; prInfo
                    dc i4'$00080010'    ; rPaper
                    dc i4'$00000000'    ; prStl
                    dc i4'$00000000'    ; prJob
                    dc i4'$00020002'    ; iDev
                    dc i4'$00020004'    ; iVRes
                    dc i4'$00020006'    ; iHRes
                    dc i4'$00080008'    ; rPage
                    dc i4'$00020018'    ; wDev
                    dc i4'$00020020'    ; feed
                    dc i4'$00020022'    ; paperType
                    dc i4'$00020024'    ; crWidth/vSizing
                    dc i4'$00020026'    ; reduction
                    dc i4'$00020050'    ; iFstPage
                    dc i4'$00020052'    ; iLstPage
                    dc i4'$00020054'    ; iCopies
                    dc i4'$00010056'    ; bJDocLoop
                    dc i4'$00040059'    ; pIdleProc
                    dc i4'$0004005D'    ; pFileName
                    dc i4'$00020051'    ; iFileVol
                    dc i4'$00010053'    ; bFileVers


; Table of pointers to all of my strings. A loop is used to go through
; this and print them all out.

TitleTable          dc i4'Title1,Title2,Title3,Title4'
                    dc i4'Title5,Title6,Title7,Title8'
                    dc i4'Title9,Title10,Title11,Title12'
                    dc i4'Title13,Title14,Title15,Title16'
                    dc i4'Title17,Title18,Title19,Title20'
                    dc i4'Title21,Title22,Title23,Title24'
                    dc i4'Title25,Title26'


; Da Strings! NOTE: Title17x is special cased in the window printing
; routine, so it isn't included in the above table.

Title1              str 'Print Record'
Title2              str 'Printer Information'
Title3              str 'Job SubRecord'
Title4              str 'Style SubRecord'
Title5              str 'prVersion = '
Title6              str 'prInfo = See Printer Information'
Title7              str 'rPaper = '
Title8              str 'prStl = See Style SubRecord'
Title9              str 'prJob = See Job SubRecord'
Title10             str 'iDev = '
Title11             str 'iVRes = '
Title12             str 'iHRes = '
Title13             str 'rPage = '
Title14             str 'wDev = '
Title15             str 'feed = '
Title16             str 'paperType = '
Title17             str 'crWidth = '
Title17x            str 'vSizing = '
Title18             str 'reduction = '
Title19             str 'iFstPage = '
Title20             str 'iLstPage = '
Title21             str 'iCopies = '
Title22             str 'bJDocLoop = '
Title23             str 'pIdleProc = '
Title24             str 'pFileName = '
Title25             str 'iFileVol = '
Title26             str 'bFileVers = '


ExtraString         ds 2

DriverChanged       str 'The Driver was changed.'
DriverDidntChange   str 'The Driver was not changed.'
Confirmed           str 'The OK Button was pressed.'
Canceled            str 'The Cancel Button was pressed.'
RecordChanged       str 'The Print Record changed.'
RecordNotChanged    dc i1'31',c'The Print Record didn''t change.'

                    end

                    copy Spy.stds.src

                    EJECT
*******************************************************************************
*
InitApp             start
*
* Description:      Create my windows, and get two handles for print records
*                   and initialize them.
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    stz QuitFlag

                    pha                 ; Create the windows that will show
                    pha                 ; the print records
                    PushLong #MyWindow2
                    _NewWindow
                    PullLong WindPointer2

                    pha                 ; space for result (window pointer)
                    pha
                    PushLong #MyWindow
                    _NewWindow
                    PullLong WindPointer

                    PushLong WindPointer ; Set the port to one of them
                    _SetPort

;
; Get a couple of handles to hold my print records
;
                    pha                 ; space for result
                    pha
                    PushLong #140       ; size of print record
                    PushWord MyID       ; put it to my name
                    PushWord #attrLocked+attrNoCross
                    PushLong #0         ; address for attributes
                    _NewHandle          ; get the handle
                    PullLong PrintRecord ; save the handle

                    pha
                    pha
                    PushLong #140       ; Size of print record
                    PushWord MyID
                    PushWord #attrLocked+attrNoCross
                    PushLong #0
                    _NewHandle
                    PullLong OldRecord

;
; Finally, call the print manager to set default values in the
; print records
;
                    PushLong PrintRecord
                    _PrDefault

                    PushLong OldRecord
                    _PrDefault

                    rts
                    end

                    EJECT
*******************************************************************************
*
CloseApp            start
*
* Description:      Close down things. This disposes of all items and memory
*                   that we allocated.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    PushLong PrintRecord
                    _DisposeHandle

                    PushLong OldRecord
                    _DisposeHandle

                    PushLong WindPointer
                    _CloseWindow

                    PushLong WindPointer2
                    _CloseWindow

                    rts
                    end

                    EJECT
*******************************************************************************
*
EventLoop           start
*
* Description:      Main Event Loop. Handle things until user selects Quit.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import MenuSelect
*                   Import ignore
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; Push on space for TaskMaster result
                    PushWord #$FFFF     ; GetNextEvent mask
                    PushLong #EventRecord
                    _TaskMaster

                    pla                 ; Get TaskMaster result
                    beq EventLoop       ; Remove if you want to use null events
                    asl A               ; Turn it into an index
                    tax
                    jsr (TaskTable,x)   ; Call appropriate event handler

                    lda QuitFlag        ; Quit selected?
                    beq EventLoop       ; no - keep looping

                    rts                 ; yes- leave the program

TaskTable           dc i2'Ignore'       ; 0 Null
                    dc i2'Ignore'       ; 1 MouseDown
                    dc i2'Ignore'       ; 2 MouseUp
                    dc i2'Ignore'       ; 3 KeyDown
                    dc i2'Ignore'       ; 4 undefined
                    dc i2'Ignore'       ; 5 AutoKey
                    dc i2'Ignore'       ; 6 Update
                    dc i2'Ignore'       ; 7 undefined
                    dc i2'Ignore'       ; 8 Activate
                    dc i2'Ignore'       ; 9 Switch
                    dc i2'Ignore'       ; 10 Desk accessory
                    dc i2'Ignore'       ; 11 Device driver
                    dc i2'Ignore'       ; 12 ap
                    dc i2'Ignore'       ; 13 ap
                    dc i2'Ignore'       ; 14 ap
                    dc i2'Ignore'       ; 15 ap
                    dc i2'Ignore'       ; TASK 0 indesk
                    dc i2'MenuSelect'   ; TASK 1 in menuBar
                    dc i2'Ignore'       ; TASK 2 in system window
                    dc i2'Ignore'       ; TASK 3 in content
                    dc i2'Ignore'       ; TASK 4 in Drag
                    dc i2'Ignore'       ; TASK 5 in grow
                    dc i2'Ignore'       ; TASK 6 in goaway
                    dc i2'Ignore'       ; TASK 7 in zoom
                    dc i2'Ignore'       ; TASK 8 in info bar
                    dc i2'Ignore'       ; TASK 9 in special menu
                    dc i2'Ignore'       ; TASK 10 in NDA
                    dc i2'Ignore'       ; TASK 11 in frame
                    dc i2'Ignore'       ; TASK 12 in drop

                    end

                    EJECT
*******************************************************************************
*
MenuSelect          start
*
* Description:      Menu item has been selected. Call the appropriate routine
*                   and unhilite the menu when it is done. Before doing so,
*                   however, a check is made to see if the routine being called
*                   could possibly change the state of the Print Record. If it
*                   can, a copy of the current print record is made. This way
*                   we can see how the routine called changed the record.
*
* Inputs:           TaskData holds menu item selected.
*
* Outputs:          NONE
*
* External Refs:
*                   Import ignore
*                   Import doAbout
*                   Import doQuit
*                   Import doPrChoose
*                   Import doPrPgSetup
*                   Import doPrJobDialog
*                   Import doPrDefault
*                   Import doPrValidate
*                   Import ClearOldRecord
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda TaskData        ; See if this call can change the
                    cmp #258            ; print record.
                    blt Dispatch        ; No - it can't. Just call the routine.

                    jsr ClearOldRecord  ; Yes - so make a copy of it
dispatch            ANOP
                    lda TaskData        ; Fet the ID of the menu item selected.
                    sec                 ; Turn it into an index.
                    sbc #250
                    asl a
                    tax
                    jsr (menuTable,x)   ; Call the routine behind it.

                    PushWord #0         ; Routine done - unhilite the menubar.
                    lda taskData+2
                    pha
                    _HiLiteMenu

                    rts

MenuTable           dc i2'Ignore'       ; undo
                    dc i2'Ignore'       ; cut
                    dc i2'Ignore'       ; copy
                    dc i2'Ignore'       ; paste
                    dc i2'Ignore'       ; clear
                    dc i2'Ignore'       ; close
                    dc i2'doAbout'
                    dc i2'doQuit'
                    dc i2'doPrChoose'
                    dc i2'doPrPgSetup'
                    dc i2'doPrJobDialog'
                    dc i2'doPrDefault'
                    dc i2'doPrValidate'
                    end
                    EJECT
*******************************************************************************
*
Ignore              start
*
* Description:      Called when I want to ignore an event.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************

                    rts
                    end

                    EJECT
*******************************************************************************
*
doQuit              start
*
* Description:      Quit routine. Set the QuitFlag to TRUE for the EventLoop.
*
*
* Inputs:           NONE
*
* Outputs:          QuitFlag set to $FFFF
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda #$FFFF
                    sta QuitFlag
                    rts
                    end

                    EJECT
*******************************************************************************
*
doPrChoose          start
*
* Description:      Called by MenuSelect to call the routine to chooose a
*                   printer. Also determine whether the print driver has
*                   changed. When it is done, it calls ShowChanges to mark the
*                   window as 'dirty', and prints a string to say whether or
*                   not the driver has changed.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import ShowChanges
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; Bring up the Choose Printer dialog
                    _PrChoosePrinter

                    jsr ShowChanges     ; Show any changes (shouldn't be any)

                    pla
                    beq NotChanged

                    lda #DriverChanged  ; if TRUE then the driver changed
                    bra done
NotChanged          lda #DriverDidntChange ; if FALSE, it didn't
done                sta ExtraString

                    rts
                    end

                    EJECT
*******************************************************************************
*
doPrPgSetup         start
*
* Description:      Called by MenuSelect to call the routine that does the page
*                   setup. Also determines whether clicked on OK or not. When
*                   it is done, it calls ShowChanges to mark the window as
*                   'dirty', and prints a string to say whether or not the
*                   user clicked on OK.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import ShowChanges
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; bring up the dialog
                    PushLong PrintRecord
                    _PrStlDialog

                    jsr ShowChanges     ; show any changes

                    pla
                    beq CancelPressed

                    lda #Confirmed      ; TRUE:  pressed OK
                    bra done
CancelPressed       lda #Canceled       ; FALSE:  pressed Cancel
done                sta ExtraString

                    rts
                    end

                    EJECT
*******************************************************************************
*
doPrJobDialog       start
*
* Description:      Called by MenuSelect to call the routine that brings up the
*                   dialog that asks how many copies, page range, etc. Also
*                   indcates if the user presses Cancel or OK. When it is done,
*                   it calls ShowChanges to mark the window as 'dirty', and
*                   prints a string to say whether or not the user clicked on
*                   OK.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import ShowChanges
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; Bring up the Job Dialog
                    PushLong PrintRecord
                    _PrJobDialog

                    jsr ShowChanges     ; Show any changes

                    pla
                    beq CancelPressed

                    lda #Confirmed      ; TRUE, so pressed OK
                    bra done
CancelPressed       lda #Canceled       ; FALSE, so pressed Cancel
done                sta ExtraString

                    rts
                    end

                    EJECT
*******************************************************************************
*
doPrDefault         start
*
* Description:      Called by MenuSelect to ask the Print Driver to fill in
*                   default values in the Print Record. This should be when an
*                   application starts up and everytime the Print Driver is
*                   changed (changing Printers does not automatically set up
*                   correct values in the Print Record). When that is done,
*                   ShowChanges is called to mark the window as 'dirty'.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import ShowChanges
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    PushLong PrintRecord
                    _PrDefault

                    jsr ShowChanges

                    stz ExtraString     ; no extra string

                    rts
                    end

                    EJECT
*******************************************************************************
*
doPrValidate        start
*
* Description:      Called by MenuSelect to verify that there are correct
*                   values in the Print record. If there are any that it
*                   suspects, it will replace them with default values. Also,
*                   PrValidate returns a boolean value to indicate if it
*                   actually changed anything. ShowChanges is called to mark
*                   the window as 'dirty', and a message is printed to say
*                   whether or not anything was changed.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import ShowChanges
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; Validate the record
                    PushLong PrintRecord
                    _PrValidate

                    jsr ShowChanges     ; Show the changes

                    pla
                    beq NoChange

                    lda #RecordChanged  ; TRUE, so yes it did change
                    bra done
NoChange            lda #RecordNotChanged ;FALSE, so no nothing changed
done                sta ExtraString

                    rts
                    end

                    EJECT
*******************************************************************************
*
DerefIt             start
*
* Description:      Utility routine that dereferences and locks a handle.
*
*
* Inputs:           A = Handle low
*                   X = Handle high
*
* Outputs:          A = Pointer Low
*                   X = Pointer high
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    sta deref           ; Put our handle into a Direct Page
                    stx deref+2         ; location so we can use it as pointer.
                    ldy #4              ; Get the Handle flags.
                    lda [deref],y
                    ora #$8000          ; Set the high bit to lock this handle.
                    sta [deref],y       ; Store it back
                    dey                 ; Now get the Master Pointer
                    dey
                    lda [deref],y
                    tax                 ; return High Word in X
                    lda [deref]         ; return Low Word in A
                    rts
                    end

                    EJECT
*******************************************************************************
*
PrUpdate            start
*
* Description:      Update routine for the Print Record window. Loop through 26
*                   strings, see if there are any Print Record fields asso-
*                   ciated with them, and print them and the values out. If the
*                   values have changed since the last Print Manager call, then
*                   boldface the string.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

; We are called from TaskMaster, with no guarantee as to the state of
; the data bank register or the direct page. Save off the ones that
; are passed to us, and set them up the way we like them.

                    phd                 ; save the Direct Page
                    phb                 ; save the Data Bank Register

                    phk                 ; set the DBR to the program bank
                    plb

                    lda MyDP            ; set the Direct Page to the main
                    tcd                 ; application's Direct Page

                    lda PrintRecord     ; deref and lock the Print Record
                    ldx PrintRecord+2
                    jsr derefIt
                    sta temp1
                    stx temp1+2

                    lda OldRecord       ; deref and lock the Previous P.R.
                    ldx OldRecord+2
                    jsr derefIt
                    sta temp2
                    stx temp2+2

                    ldx #4*25           ; 4 times (number of strings - 1)
loop                ANOP
                    stx Index           ; Save the index into memory

; Determine what this string represents (whether it identifies a field that
; has a changeable value or not) and find out if it did indeed change. If
; so, then set the fontface to BoldFace. If not, then set the fontface to
; plain.
                    jsr SetFontStyle

; Find out where this string is supposed to go and move there.

                    ldx Index
                    PushWord Position,x
                    PushWord Position+2,x
                    _MoveTo

;
; Prepare to print the string. This is normally just a lookup into
; a table of string pointers to get the one we want. However, we need
; to special case the name of one field, which changes depending on
; whether or not we are using a LaserWriter.

                    ldx Index
                    cpx #4*16           ; is the crWidth/vSizing one?
                    bne doNormal        ; no, so just draw it

                    ldy #oPrInfo+oiDev  ; do we have a LaserWriter?
                    lda [temp1],y
                    cmp #3
                    bne doNormal        ; yes, so use default string

                    PushLong #Title17x  ; no, so substitute in Special String
                    bra DrawTitle       ; now print it
doNormal            ANOP
                    PushLong TitleTable,x ; put on the normal string
DrawTitle           ANOP
                    _DrawString         ; print the string

                    jsr PrintValues     ; print the field's values

; Now see if there is an extra message to print. If so, then do it.

                    lda ExtraString     ; is there one?
                    beq EndLoop         ; No, so skip over this next part.

                    PushWord #20        ; move to the right place
                    PushWord #150
                    _MoveTo

                    phk                 ; create a high order word out of
                    phk                 ; our program bank register.
                    pla
                    and #$00FF
                    pha
                    PushWord ExtraString ; push on the low order word.
                    _DrawString         ; draw the string.

EndLoop             ANOP
                    ldx Index           ; get our index back
                    dex                 ; bump to the next value
                    dex
                    dex
                    dex
                    bpl loop            ; keep going if still positive

                    plb                 ; restore the DBR...
                    pld                 ; ... and the Direct Page

                    rtl                 ; return back to TaskMaster

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; If the item to be printed is one of the last 4, then it is a column
; title. BoldFace it and leave. If it is not a column title, then see
; if that part of the print record has changed. If so, then set the
; font style to bold and leave. Otherwise, set the font style to normal.
;

SetFontStyle        ANOP
                    PushWord #0         ; assume normal text
                    _SetTextFace

                    ldx Index
                    cpx #4*4            ; time to Bold for column headerss?
                    bge ckChange        ; no, see if print record changed

                    PushWord #%00001    ; turn on boldfacing
                    _SetTextFace

                    bra done2           ; and leave

ckChange            ANOP
                    lda ValueOffsets+2,x ; can this one change?
                    beq done2           ; no so don't check
                    sta count           ; check this many bytes

                    lda ValueOffsets,x  ; get location of field to check
                    tay

                    SHORTM              ; do the checks in 8-bit mode
ckChngLoop          ANOP
                    lda [temp1],y       ; get the new byte
                    cmp [temp2],y       ; check against the old
                    bne different       ; if even one's different, boldface it
                    iny                 ; bump to next byte to check
                    dec count           ; have we done them all?
                    bne ckChngLoop      ; no, so keep going
                    LONGM               ; back to 16-bit mode
                    bra done2           ; didn't change so leave in normal mode

different           ANOP
                    LONGM               ; back to 16-bit mode
                    PushWord #%00001    ; item changed, bold it
                    _SetTextFace

done2               ANOP
                    rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Print out the record values.
;

PrintValues         ANOP
                    PushWord #0         ; normal text
                    _SetTextFace

                    ldx Index
                    lda ValueOffsets+2,x ; does this entry have field values
                    beq done            ; no so don't print anything
                    sta count           ; save the number of bytes to print

                    lda ValueOffsets,x  ; get location of bytes to print
                    tay

PrintValueLoop      ANOP
                    sty YSave           ; Save this record index
                    lda [temp1],y       ; get the byte
                    and #$00FF          ; mask off upper byte

                    pha                 ; push the value to be converted
                    PushLong #ValueString ; put the HEX string here
                    PushWord #2         ; length of output is 2
                    _Int2Hex            ; convert byte to a Hex string

                    PushLong #ValueString ; now print it
                    _DrawCString

                    dec count           ; have we done all of them?
                    beq done            ; yes, so leave

                    pea ","             ; no, so print a comma and do the next
                    _DrawChar
                    ldy YSave
                    iny
                    bra PrintValueLoop

done                ANOP
                    rts

Index               ds 2
YSave               ds 2
count               ds 2
OffSet              ds 2
ValueString         dc i1'0,0,0'

                    end

                    EJECT
*******************************************************************************
*
PrOldUpdate         start
*
* Description:      Update routine for the Previous record window. This is
*                   almost exactly the same as PrUpdate, but does not check to
*                   see if the old record has changed when it determines the
*                   font style for the strings. See that routine for comments.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    phd
                    phb

                    phk
                    plb

                    lda MyDP
                    tcd

                    lda PrintRecord
                    ldx PrintRecord+2
                    jsr derefIt
                    sta temp1
                    stx temp1+2

                    lda OldRecord
                    ldx OldRecord+2
                    jsr derefIt
                    sta temp2
                    stx temp2+2

                    ldx #4*25           ; 4 times number of strings - 1
loop                ANOP
                    stx Index

                    jsr SetFontStyle

                    ldx Index
                    lda Position,x
                    pha
                    lda Position+2,x
                    pha
                    _MoveTo

                    ldx Index
                    cpx #4*16           ; is the crWidth/Sizing one?
                    bne doNormal        ; no, so just draw it

                    ldy #oPrInfo+oiDev  ; do we have a LaserWriter?
                    lda [temp2],y
                    cmp #3
                    bne doNormal        ; yes, so use default string

                    PushLong #Title17x
                    bra DrawTitle
doNormal            ANOP
                    lda TitleTable+2,x
                    pha
                    lda TitleTable,x
                    pha
DrawTitle           ANOP
                    _DrawString

                    jsr PrintValues

                    ldx Index
                    dex
                    dex
                    dex
                    dex
                    bpl loop

                    plb
                    pld

                    rtl

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; If the item to be printed is one of the last 4, then it is a column
; title. BoldFace it and leave. If it is not a column title, then see
; if that part of the print record has changed. If so, then set the
; font style to italic and leave. Otherwise, set the font style to
; normal.
;

SetFontStyle        ANOP
                    PushWord #0         ; assume normal text
                    _SetTextFace

                    ldx Index
                    cpx #4*4            ; time to go to bold?
                    bge done2           ; no, see if print record changed

                    PushWord #%00001    ; turn on boldfacing
                    _SetTextFace

done2               ANOP
                    rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Print out the record values
;

PrintValues         ANOP
                    PushWord #0         ; normal text
                    _SetTextFace

                    ldx Index
                    lda ValueOffsets+2,x ; can this one change?
                    beq done            ; no so don't check
                    sta count

                    lda ValueOffsets,x
                    tay

PrintValueLoop      ANOP
                    sty YSave           ; Save this record index
                    lda [temp2],y
                    and #$00FF

                    pha                 ; push the value to be converted
                    PushLong #ValueString
                    PushWord #2         ; length of output is 2
                    _Int2Hex

                    PushLong #ValueString
                    _DrawCString

                    dec count           ; have we done all of them?
                    beq done            ; yes, so leave

                    pea ","             ; no, so print a comma and do the next
                    _DrawChar
                    ldy YSave
                    iny
                    bra PrintValueLoop

done                ANOP
                    rts

Index               ds 2
YSave               ds 2
count               ds 2
OffSet              ds 2
ValueString         dc i1'0,0,0'

                    end

                    EJECT
*******************************************************************************
*
ClearOldRecord      start
*
* Description:      We are about to make a call that could change the Print
*                   data! Back up the current print record into the Previous
*                   Print Record.
*
*
* Inputs:           'PrintRecord' holds handle or record to back up
*                   'OldRecord' holds handle to back it up to
*
* Outputs:          'OldRecord' contains copy of 'PrintRecord' contents
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    PushLong PrintRecord ; Source Handle
                    PushLong OldRecord  ; Destination Handle
                    PushLong #140       ; Length of the Source.
                    _HandToHand         ; Move it.

                    rts
                    end

                    EJECT
*******************************************************************************
*
ShowChanges         start
*
* Description:      We have made a call the could have changed the Print
*                   data. Erase the old display of the print record, and mark
*                   the screen as invalid so that TaskMaster will update it
*                   with the new values.
*
*
* Inputs:           NONE
*
* Outputs:          Port set to 'Current Setting' window
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; save the old port, as we are chang-
                    pha                 ; ing it below to erase the windows.
                    _GetPort

; first erase and invalidate the Previous Print Record window

                    PushLong WindPointer2
                    _SetPort

                    PushLong #BigRect
                    _EraseRect

                    PushLong #BigRect
                    _InvalRect

; Then erase and invalidate the current Print Record window.

                    PushLong WindPointer
                    _SetPort

                    PushLong #BigRect
                    _EraseRect

                    PushLong #BigRect
                    _InvalRect

                    _SetPort

                    rts
                    end

                    EJECT
*******************************************************************************
*
DisableAll          start
*
* Description:      Disables all menu items between 257 and 266. This includes
*                   virtually everything in the File Menu. This call will
*                   usually be followed by a call to re-enable one or two File
*                   items.
*
*
* Inputs:           NONE
*
* Outputs:          Menu items 257-266 disabled
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda #257            ; start with the Quit item
                    sta MItemNum        ; save the index around the call
Loop                ANOP
                    pha                 ; push on for DisableItem
                    _DisableMItem
                    inc MItemNum        ; Bump to next Menu Item
                    lda MItemNum
                    cmp #267            ; finish with the Close Doc item
                    blt Loop

                    rts

MItemNum            ds 2

                    end

                    EJECT
*******************************************************************************
*
EnableAll           start
*
* Description:      Enables all menu items between 257 and 266. This includes
*                   virtually everything in the File Menu.
*
*
* Inputs:           NONE
*
* Outputs:          Menu items 257-266 enabled
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda #257            ; start with the Quit item
                    sta MItemNum

Loop                pha
                    _EnableMItem

                    inc MItemNum
                    lda MItemNum
                    cmp #267            ; finish with the Close Doc item
                    blt Loop

                    rts

MItemNum            ds 2

                    end

                    END
